package com.orange.lswidget.widgets.musicplayer.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.SystemClock;
import android.view.MotionEvent;

import com.orange.lswidget.widgets.musicplayer.MusicPlayerClient;
import com.orange.util.Constants;
import com.orange.util.LogHelper;

public class MusicBroadcastReceiver extends BroadcastReceiver {
	private static final String	TAG				= "MusicBroadcastReceiver";

	private long				mStartTime;
	private int					mRepeatCount;
	private Handler				mHandler		= new Handler();
	private long				mStartSeekPos	= 0;
	private long				mLastSeekEventTime;

	private Runnable			mNextRepeater	= new NextRepeater();
	private Runnable			mPrevRepeater	= new PreRepeater();

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		LogHelper.v(TAG, "onReceive. action: " + action);

		if (Constants.ACTION_MUSIC_NEXT_LONGCLICK.equalsIgnoreCase(action)) {
			mStartTime = SystemClock.elapsedRealtime();
			mRepeatCount = 0;
			mHandler.post(mNextRepeater);
		} else if (Constants.ACTION_MUSIC_NEXT_CLICK.equalsIgnoreCase(action)) {
			int extra = intent.getIntExtra(Constants.KEY_MUSIC_BTN_NEXT, -1);
			if (extra == MotionEvent.ACTION_UP
					|| extra == MotionEvent.ACTION_CANCEL) {
				mHandler.removeCallbacks(mNextRepeater);

				if (mStartTime != 0) {
					long now = SystemClock.elapsedRealtime();
					scanForward(-1, now - mStartTime);
					mStartTime = 0;
				}
			}
		} else if (Constants.ACTION_MUSIC_PREV_LONGCLICK
				.equalsIgnoreCase(action)) {
			mStartTime = SystemClock.elapsedRealtime();
			mRepeatCount = 0;
			mHandler.post(mPrevRepeater);
		} else if (Constants.ACTION_MUSIC_PREV_CLICK.equalsIgnoreCase(action)) {
			int extra = intent.getIntExtra(Constants.KEY_MUSIC_BTN_PREV, -1);
			if (extra == MotionEvent.ACTION_UP
					|| extra == MotionEvent.ACTION_CANCEL) {
				mHandler.removeCallbacks(mPrevRepeater);

				if (mStartTime != 0) {
					long now = SystemClock.elapsedRealtime();
					scanBackward(-1, now - mStartTime);
					mStartTime = 0;
				}
			}
		}
	}

	private class NextRepeater implements Runnable {
		public void run() {
			LogHelper.v(TAG, " =======mNextRepeater===");
			long now = SystemClock.elapsedRealtime();
			scanForward(mRepeatCount++, now - mStartTime);
			mHandler.postDelayed(this, 260);
		}

	}

	private class PreRepeater implements Runnable {

		public void run() {
			LogHelper.v(TAG, "=======mPrevRepeater===");
			long now = SystemClock.elapsedRealtime();
			scanBackward(mRepeatCount++, now - mStartTime);
			mHandler.postDelayed(this, 260);
		}

	}

	private void scanForward(int repcnt, long delta) {
		IMusicPlayerService mMPSystemService = MusicPlayerClient
				.getSystemMPService();

		if (mMPSystemService == null)
			return;
		if (repcnt == 0) {
			mStartSeekPos = mMPSystemService.position();
			mLastSeekEventTime = 0;
		} else {
			if (delta < 5000) {
				// seek at 10x speed for the first 5 seconds
				delta = delta * 10;
			} else {
				// seek at 40x after that
				delta = 50000 + (delta - 5000) * 40;
			}
			long newpos = mStartSeekPos + delta;
			long duration = mMPSystemService.duration();
			if (newpos >= duration) {
				// move to next track
				mMPSystemService.next();
				mStartSeekPos -= duration; // is OK to go negative
				newpos -= duration;
			}
			if (((delta - mLastSeekEventTime) > 250) || repcnt < 0) {
				mMPSystemService.seek(newpos);
				mLastSeekEventTime = delta;
			}
		}
	}

	private void scanBackward(int repcnt, long delta) {
		IMusicPlayerService mMPSystemService = MusicPlayerClient
				.getSystemMPService();

		if (mMPSystemService == null)
			return;
		if (repcnt == 0) {
			mStartSeekPos = mMPSystemService.position();
			mLastSeekEventTime = 0;
		} else {
			if (delta < 5000) {
				// seek at 10x speed for the first 5 seconds
				delta = delta * 10;
			} else {
				// seek at 40x after that
				delta = 50000 + (delta - 5000) * 40;
			}
			long newpos = mStartSeekPos - delta;
			if (newpos < 0) {
				// move to previous track
				mMPSystemService.prev();
				long duration = mMPSystemService.duration();
				mStartSeekPos += duration;
				newpos += duration;
			}
			if (((delta - mLastSeekEventTime) > 250) || repcnt < 0) {
				mMPSystemService.seek(newpos);
				mLastSeekEventTime = delta;
			}
		}
	}
}
